//
// Created by 猎人猪 on 2023/2/26.
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "common.h"
#include "ecu.h"
#include "sponge.h"
#include "CCL.h"


ECU_store ecu_store;
ECU_temp_store ecu_temp_store;

// ECU注册阶段-分配密钥
void ecu_reg(unsigned char ID[2],unsigned char key[KEY_LENGTH_BYTES])
{
    for(int i=0;i<2;++i)
    {
        ecu_store.ID[i]=ID[i];
    }
    for(int i=0;i<KEY_LENGTH_BYTES;++i)
    {
        ecu_store.k[i]=key[i];
    }
    ecu_store.f=0;
}

// 认证阶段-响应请求
AUTH_response ecu_auth_response(AUTH_request request)
{
    srand((unsigned) time(NULL));
    int r2=rand();
    unsigned char hash_plain[SIZE_INT*2+KEY_LENGTH_BYTES];
    unsigned char hash_result[SHA3_RESULT_LENGTH_BYTES];
    unsigned char *p_temp;

    memcpy(hash_plain,&request.r1,SIZE_INT);
    memcpy(hash_plain+SIZE_INT,&r2,SIZE_INT);
    memcpy(hash_plain+SIZE_INT*2, ecu_store.k, KEY_LENGTH_BYTES);

    p_temp = sponge(hash_plain, sizeof(hash_plain));
    memcpy(hash_result,p_temp,SHA3_RESULT_LENGTH_BYTES);

    memcpy(ecu_temp_store.c1, hash_result, KEY_LENGTH_BYTES);
    memcpy(ecu_temp_store.c3, hash_result + KEY_LENGTH_BYTES * 2, KEY_LENGTH_BYTES);
    memcpy(ecu_temp_store.c4, hash_result + KEY_LENGTH_BYTES * 3, KEY_LENGTH_BYTES);

    AUTH_response response;
    response.r2=r2;
    memcpy(response.c2,hash_result+KEY_LENGTH_BYTES,KEY_LENGTH_BYTES);
    response.f=ecu_store.f;

    return response;

}

// 认证阶段-密钥验证
void ecu_auth_confirm(AUTH_verify verify)
{
    if(memcmp(ecu_temp_store.c3, verify.c3, KEY_LENGTH_BYTES))
    {
        cclPrintf("ecu: authentication failed!");
        exit(-1);
    }
    else
    {
        cclPrintf("ecu: authentication passed!");
    }
    memcpy(ecu_store.k, ecu_temp_store.c1, KEY_LENGTH_BYTES);
    ecu_store.f= (ecu_store.f + 1) % 2;
    unsigned char sk[KEY_LENGTH_BYTES];
    calculate_sk(ecu_temp_store.c3, ecu_temp_store.c4, sk);

    cclPrintf("sk on gateway side is:");
    char print_buf[KEY_LENGTH_BYTES * 2 + 1];
    arrayToStr(sk, KEY_LENGTH_BYTES, print_buf);
    print_buf[KEY_LENGTH_BYTES * 2] = '\0';
    cclPrintf("%s", print_buf);

}